/*
 * Copyright (C) 2010 Seapeak.Xu
 *
 * fostmq may be copied only under the terms of the GNU General
 * Public License V3, which may be found in the fostmq source kit.
 *
 * Created on: 2010-7-30
 * Author: Seapeak.Xu
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>


#include "fost_datetime.h"
#include "fost_mgnb.h"
/*
 * format the datetime to string without the internal operator
 * parameters:
 * 	datetime:the format datetime,but it maybe null
 * 	bufflen:the format buffer length,it contains the end-char 'null' or '\0'
 * 	buff:the format buffer
 * remarks:
 * 	when the datetime is null the datetime is now
 * 	the length equal or more than 15
 */
char *format_datetime(const struct tm *datetime, const size_t bufflen, char *buff)
{
	size_t len = DATETIME_LEN_NOSEPY < bufflen ?  DATETIME_LEN_NOSEPY : bufflen; 

	if (NULL == datetime)
	{
		time_t timep;
		time(&timep);
		struct tm *datetime_temp = localtime(&timep);	
		
		snprintf(buff, len, "%04d%02d%02d%02d%02d%02d", datetime_temp->tm_year				
			+ 1900, datetime_temp->tm_mon + 1, datetime_temp->tm_mday,
			datetime_temp->tm_hour, datetime_temp->tm_min,
			datetime_temp->tm_sec);
	}
	else
	{
		snprintf(buff, len, "%04d%02d%02d%02d%02d%02d", datetime->tm_year
			+ 1900, datetime->tm_mon + 1, datetime->tm_mday,
			datetime->tm_hour, datetime->tm_min,
			datetime->tm_sec);
	}

	*(buff + len) = '\0';
	return buff;
}

/*
 * format the datetime to string with the internal operator
 * parameters:
 * 	datetime:the format datetime,but it maybe null
 * 	bufflen:the format buffer length,it contains the internal operatorand  the end-char 'null' or '\0'
 * 	buff:the format buffer
 * remarks:
 * 	when the datetime is null the datetime is now
 * 	the internal operator is '-' in yyyy-MM-day,and ':' in hh:mm:ss,the space between the days and hours
 * 	the length is equal or more then 20
 */
char *format_datetime_by_separator(const struct tm *datetime,
		const size_t bufflen, char *buff)
{
	size_t len = DATETIME_LEN_SEPY < bufflen ? DATETIME_LEN_SEPY : bufflen; 

	if (NULL == datetime)
	{
		time_t timep;
		time(&timep);
		struct tm *datetime_temp = localtime(&timep);
		snprintf(buff, len, "%04d-%02d-%02d %02d:%02d:%02d",
			datetime_temp->tm_year + 1900, datetime_temp->tm_mon + 1,
			datetime_temp->tm_mday, datetime_temp->tm_hour,
			datetime_temp->tm_min, datetime_temp->tm_sec);
	}
	else
	{
		snprintf(buff, len, "%04d-%02d-%02d %02d:%02d:%02d",
			datetime->tm_year + 1900, datetime->tm_mon + 1,
			datetime->tm_mday, datetime->tm_hour,
			datetime->tm_min, datetime->tm_sec);
	}

	*(buff + len) = '\0';
	return buff;
}

/*
 * get the datetime span
 * parameters:
 * 	result:the span from start datetime to end datetime
 * 	start:the start datetime
 * 	end:the end datetime
 * remarks:
 * 	the start and end must no-null
 */
int timeval_subtract(struct timeval *result,const struct timeval *start,
		const struct timeval *end)
{
	if (start->tv_sec > end->tv_sec)
		return -1;

	if ((start->tv_sec == end->tv_sec) && (start->tv_usec > end->tv_usec))
		return -1;

	result->tv_sec = (end->tv_sec - start->tv_sec);
	result->tv_usec = (end->tv_usec - start->tv_usec);

	if (result->tv_usec < 0)
	{
		result->tv_sec--;
		result->tv_usec += 1000000;
	}

	return 0;
}


int istimeout(struct tm *start,struct tm *end,time_t val)
{
	if(NULL == start)
	{
		errno = EINVAL;
		return -1;
	}
	time_t end_time;
	if(NULL == end)
	{
		time_t now;
		time(&now);
		struct tm *now_tm = localtime(&now);
		end_time = mktime(now_tm);

	}
	else
	{
		end_time = mktime(end);
	}
	
	time_t start_time = mktime(start);
	
	time_t span = end_time - start_time - val;

	return 0 <= span ? 1 : 0;
}
